package logic

import (
	"context"
	"time"

	"googee/common/errorx"
	"googee/common/utils"
	"googee/service/account/rpc/account"
	"googee/service/user/api/internal/svc"
	"googee/service/user/api/internal/types"
	"googee/service/user/rpc/user"

	"github.com/dtm-labs/dtmcli/dtmimp"
	"github.com/dtm-labs/dtmgrpc"
	"github.com/fatih/color"
	"github.com/jinzhu/copier"
	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type RegisterLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
	return &RegisterLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterReply, err error) {
	accountRpcBusiServer, err := l.svcCtx.Config.Account.BuildTarget()
	dtmimp.FatalIfError(err)
	resp = &types.RegisterReply{}
	name := user.RegisterNameRequest{Name: req.Username, Password: req.Password}
	u, err := l.svcCtx.User.RegisterUserByName(l.ctx, &name)
	if err != nil {
		st, ok := status.FromError(err)
		if ok {
			color.Red("err:%v", st)
			if st.Code() == codes.InvalidArgument {
				return nil, errorx.NewCodeError(errorx.USER_ERROR+2, st.Message())
			} else if st.Code() == codes.AlreadyExists {
				return nil, errorx.NewCodeErrorNoMsg(errorx.USER_ERROR + 3)
			} else {
				return nil, errorx.NewCodeError(errorx.INTERNAL_ERROR, "系统内部未知错误")
			}
		} else {
			return nil, errorx.NewCodeError(errorx.INTERNAL_ERROR, "系统内部未知错误")
		}
	}

	gid := dtmgrpc.MustGenGid(l.svcCtx.Config.DtmServer)
	msg := dtmgrpc.NewMsgGrpc(l.svcCtx.Config.DtmServer, gid).Add(
		accountRpcBusiServer+"/account.Account/createAccount", &account.IdRequest{
			Id: u.Id})

	err = msg.Submit()
	dtmimp.FatalIfError(err)

	_ = copier.Copy(&resp.Data.User, u)

	now := time.Now().Unix()
	accessExpire := l.svcCtx.Config.Auth.AccessExpire

	jwt, err := utils.GetJwtToken(l.svcCtx.Config.Auth.AccessSecret, now, accessExpire, u.Id)
	color.Red("jwt=%v", jwt)
	if err != nil {
		color.Red("err:%v", err)
	}
	resp.Data.JWT.AccessExpire = now + accessExpire
	resp.Data.JWT.RefreshAfter = now + accessExpire/2
	resp.Data.JWT.AccessToken = jwt

	return resp, nil
}
